<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>🌟 Vue 3 响应式升级路线图 - 成为小法师的奇幻之旅</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <style>
    @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;700&display=swap');
    
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    body {
      font-family: 'Noto Sans SC', sans-serif;
      background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
      min-height: 100vh;
      padding: 20px;
      overflow-x: hidden;
    }
    
    .magic-container {
      max-width: 1200px;
      margin: 0 auto;
      background: rgba(255, 255, 255, 0.95);
      border-radius: 20px;
      padding: 40px;
      box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
      backdrop-filter: blur(10px);
      position: relative;
      overflow: hidden;
    }
    
    .magic-container::before {
      content: '';
      position: absolute;
      top: -50%;
      left: -50%;
      width: 200%;
      height: 200%;
      background: linear-gradient(45deg, transparent, rgba(255, 255, 255, 0.1), transparent);
      animation: magic-shine 3s infinite;
    }
    
    @keyframes magic-shine {
      0% { transform: translateX(-100%) translateY(-100%) rotate(45deg); }
      100% { transform: translateX(100%) translateY(100%) rotate(45deg); }
    }
    
    .title {
      text-align: center;
      font-size: 42px;
      font-weight: 700;
      background: linear-gradient(135deg, #667eea, #764ba2, #f093fb);
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      background-clip: text;
      margin-bottom: 20px;
      position: relative;
      z-index: 1;
      animation: title-glow 2s ease-in-out infinite alternate;
    }
    
    @keyframes title-glow {
      from { filter: drop-shadow(0 0 5px rgba(102, 126, 234, 0.5)); }
      to { filter: drop-shadow(0 0 20px rgba(240, 147, 251, 0.8)); }
    }
    
    .subtitle {
      text-align: center;
      font-size: 18px;
      color: #666;
      margin-bottom: 40px;
      position: relative;
      z-index: 1;
    }
    
    .progress-overview {
      background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 50%, #fecfef 100%);
      border-radius: 15px;
      padding: 30px;
      margin-bottom: 30px;
      text-align: center;
      position: relative;
      overflow: hidden;
    }
    
    .progress-overview::before {
      content: '✨';
      position: absolute;
      top: 10px;
      right: 20px;
      font-size: 24px;
      animation: sparkle 2s ease-in-out infinite;
    }
    
    @keyframes sparkle {
      0%, 100% { transform: scale(1) rotate(0deg); }
      50% { transform: scale(1.2) rotate(180deg); }
    }
    
    .level-counter {
      font-size: 48px;
      font-weight: bold;
      color: white;
      margin-bottom: 10px;
      text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
    }
    
    .progress-bar-container {
      background: rgba(255, 255, 255, 0.3);
      border-radius: 25px;
      height: 20px;
      margin: 20px 0;
      overflow: hidden;
      position: relative;
    }
    
    .progress-bar {
      background: linear-gradient(90deg, #667eea, #764ba2, #f093fb);
      height: 100%;
      border-radius: 25px;
      transition: width 0.8s ease;
      position: relative;
      overflow: hidden;
    }
    
    .progress-bar::after {
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
      animation: progress-shine 2s infinite;
    }
    
    @keyframes progress-shine {
      0% { transform: translateX(-100%); }
      100% { transform: translateX(100%); }
    }
    
    .progress-text {
      font-size: 18px;
      color: white;
      font-weight: 500;
    }
    
    .roadmap {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
      gap: 20px;
      margin-top: 30px;
    }
    
    .stage {
      background: white;
      border-radius: 15px;
      padding: 25px;
      box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
      transition: all 0.3s ease;
      position: relative;
      overflow: hidden;
    }
    
    .stage:hover {
      transform: translateY(-5px);
      box-shadow: 0 15px 40px rgba(0, 0, 0, 0.15);
    }
    
    .stage.completed {
      background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
      border: 2px solid #27ae60;
    }
    
    .stage.current {
      background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%);
      border: 2px solid #ff6b6b;
      animation: current-pulse 2s infinite;
    }
    
    @keyframes current-pulse {
      0% { box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); }
      50% { box-shadow: 0 10px 30px rgba(255, 107, 107, 0.3); }
      100% { box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); }
    }
    
    .stage.locked {
      background: #f8f9fa;
      border: 2px solid #dee2e6;
      opacity: 0.7;
    }
    
    .stage-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 15px;
    }
    
    .stage-title {
      font-size: 20px;
      font-weight: 600;
      color: #2d3748;
    }
    
    .stage-icon {
      font-size: 24px;
      width: 40px;
      height: 40px;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      transition: all 0.3s ease;
    }
    
    .stage.completed .stage-icon {
      background: #27ae60;
      color: white;
      animation: bounce 0.6s ease;
    }
    
    .stage.current .stage-icon {
      background: #ff6b6b;
      color: white;
      animation: rotate 2s linear infinite;
    }
    
    .stage.locked .stage-icon {
      background: #dee2e6;
      color: #6c757d;
    }
    
    @keyframes bounce {
      0%, 20%, 60%, 100% { transform: translateY(0); }
      40% { transform: translateY(-10px); }
      80% { transform: translateY(-5px); }
    }
    
    @keyframes rotate {
      from { transform: rotate(0deg); }
      to { transform: rotate(360deg); }
    }
    
    .stage-description {
      color: #666;
      font-size: 14px;
      line-height: 1.6;
      margin-bottom: 15px;
    }
    
    .stage-actions {
      display: flex;
      gap: 10px;
      flex-wrap: wrap;
    }
    
    .btn {
      padding: 8px 16px;
      border: none;
      border-radius: 20px;
      font-size: 14px;
      font-weight: 500;
      cursor: pointer;
      transition: all 0.3s ease;
      text-decoration: none;
      display: inline-flex;
      align-items: center;
      gap: 5px;
    }
    
    .btn-primary {
      background: linear-gradient(135deg, #667eea, #764ba2);
      color: white;
    }
    
    .btn-primary:hover {
      transform: translateY(-2px);
      box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
    }
    
    .btn-success {
      background: linear-gradient(135deg, #27ae60, #2ecc71);
      color: white;
    }
    
    .btn-warning {
      background: linear-gradient(135deg, #f39c12, #e67e22);
      color: white;
    }
    
    .btn:disabled {
      opacity: 0.6;
      cursor: not-allowed;
      transform: none !important;
    }
    
    .achievement {
      background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%);
      border-radius: 15px;
      padding: 20px;
      margin-top: 30px;
      text-align: center;
      position: relative;
      overflow: hidden;
    }
    
    .achievement-title {
      font-size: 24px;
      font-weight: bold;
      color: #d63031;
      margin-bottom: 10px;
    }
    
    .achievement-description {
      color: #2d3748;
      font-size: 16px;
      margin-bottom: 15px;
    }
    
    .achievement-progress {
      font-size: 18px;
      font-weight: bold;
      color: #e17055;
    }
    
    .tips {
      background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
      border-radius: 15px;
      padding: 20px;
      margin-top: 20px;
    }
    
    .tips-title {
      font-size: 18px;
      font-weight: bold;
      color: #2d3748;
      margin-bottom: 10px;
      display: flex;
      align-items: center;
      gap: 10px;
    }
    
    .tips-content {
      color: #4a5568;
      line-height: 1.6;
    }
    
    .floating-icons {
      position: fixed;
      pointer-events: none;
      z-index: 1000;
    }
    
    .floating-icon {
      position: absolute;
      font-size: 20px;
      animation: float 6s ease-in-out infinite;
      opacity: 0.7;
    }
    
    @keyframes float {
      0%, 100% { transform: translateY(0px) rotate(0deg); }
      50% { transform: translateY(-20px) rotate(180deg); }
    }
    
    .stats-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
      gap: 15px;
      margin-top: 20px;
    }
    
    .stat-card {
      background: rgba(255, 255, 255, 0.9);
      border-radius: 10px;
      padding: 15px;
      text-align: center;
      transition: all 0.3s ease;
    }
    
    .stat-card:hover {
      transform: translateY(-3px);
      box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
    }
    
    .stat-number {
      font-size: 24px;
      font-weight: bold;
      color: #667eea;
    }
    
    .stat-label {
      font-size: 12px;
      color: #666;
      margin-top: 5px;
    }
    
    @media (max-width: 768px) {
      .magic-container {
        padding: 20px;
        margin: 10px;
      }
      
      .title {
        font-size: 32px;
      }
      
      .roadmap {
        grid-template-columns: 1fr;
      }
      
      .stage-actions {
        flex-direction: column;
      }
      
      .btn {
        width: 100%;
        justify-content: center;
      }
    }
  </style>
</head>
<body>
  <div id="app">
    <!-- 浮动装饰图标 -->
    <div class="floating-icons">
      <div class="floating-icon" style="top: 10%; left: 10%; animation-delay: 0s;">⭐</div>
      <div class="floating-icon" style="top: 20%; right: 15%; animation-delay: 1s;">✨</div>
      <div class="floating-icon" style="top: 60%; left: 5%; animation-delay: 2s;">🌟</div>
      <div class="floating-icon" style="top: 80%; right: 10%; animation-delay: 3s;">💫</div>
      <div class="floating-icon" style="top: 40%; left: 90%; animation-delay: 4s;">🎯</div>
    </div>

    <div class="magic-container">
      <h1 class="title">🌟 Vue 3 响应式升级路线图</h1>
      <p class="subtitle">成为"Vue3 响应式小法师"的奇幻之旅</p>
      
      <!-- 进度总览 -->
      <div class="progress-overview">
        <div class="level-counter">{{ completedCount }}/20 ✅</div>
        <div class="progress-bar-container">
          <div class="progress-bar" :style="{ width: progressPercentage + '%' }"></div>
        </div>
        <div class="progress-text">{{ progressText }}</div>
      </div>

      <!-- 统计信息 -->
      <div class="stats-grid">
        <div class="stat-card">
          <div class="stat-number">{{ completedCount }}</div>
          <div class="stat-label">已完成关卡</div>
        </div>
        <div class="stat-card">
          <div class="stat-number">{{ currentStageIndex + 1 }}</div>
          <div class="stat-label">当前进度</div>
        </div>
        <div class="stat-card">
          <div class="stat-number">{{ remainingCount }}</div>
          <div class="stat-label">剩余关卡</div>
        </div>
        <div class="stat-card">
          <div class="stat-number">{{ Math.round(progressPercentage) }}%</div>
          <div class="stat-label">完成度</div>
        </div>
      </div>

      <!-- 升级路线图 -->
      <div class="roadmap">
        <div 
          v-for="(stage, index) in roadmap" 
          :key="index"
          class="stage"
          :class="{
            'completed': stage.completed,
            'current': index === currentStageIndex,
            'locked': index > currentStageIndex + 1
          }"
        >
          <div class="stage-header">
            <div class="stage-title">{{ stage.title }}</div>
            <div class="stage-icon">
              <span v-if="stage.completed">✅</span>
              <span v-else-if="index === currentStageIndex">🎯</span>
              <span v-else>🔒</span>
            </div>
          </div>
          
          <div class="stage-description">{{ stage.description }}</div>
          
          <div class="stage-actions">
            <button 
              v-if="!stage.completed && index <= currentStageIndex + 1"
              @click="startStage(index)"
              class="btn"
              :class="index === currentStageIndex ? 'btn-primary' : 'btn-warning'"
              :disabled="index > currentStageIndex"
            >
              <span v-if="index === currentStageIndex">🚀 开始学习</span>
              <span v-else>⏳ 等待解锁</span>
            </button>
            
            <button 
              v-if="stage.completed"
              @click="reviewStage(index)"
              class="btn btn-success"
            >
              📚 复习巩固
            </button>
            
            <a 
              v-if="stage.link && (stage.completed || index <= currentStageIndex)"
              :href="stage.link" 
              target="_blank"
              class="btn btn-primary"
            >
              🔗 前往关卡
            </a>
          </div>
        </div>
      </div>

      <!-- 成就系统 -->
      <div class="achievement" v-if="completedCount >= 20">
        <div class="achievement-title">🏆 恭喜！你已成为"Vue3 响应式小法师"！</div>
        <div class="achievement-description">
          你已经掌握了Vue 3响应式系统的所有核心概念，可以自信地应对各种开发挑战！
        </div>
        <div class="achievement-progress">
          🎉 成就解锁：响应式大师 {{ completedCount }}/20 ✅
        </div>
      </div>

      <div class="achievement" v-else-if="completedCount >= 15">
        <div class="achievement-title">🌟 优秀！"Vue3 响应式进阶者"</div>
        <div class="achievement-description">
          你已经掌握了大部分核心概念，继续加油冲刺最终目标！
        </div>
        <div class="achievement-progress">
          还差 {{ 20 - completedCount }} 个✅ 就能成为小法师啦！
        </div>
      </div>

      <div class="achievement" v-else-if="completedCount >= 10">
        <div class="achievement-title">✨ 不错！"Vue3 响应式学徒"</div>
        <div class="achievement-description">
          你已经掌握了基础概念，继续深入学习更高级的内容！
        </div>
        <div class="achievement-progress">
          进度：{{ completedCount }}/20 ✅，继续加油！
        </div>
      </div>

      <div class="achievement" v-else-if="completedCount >= 5">
        <div class="achievement-title">🎯 很好！"Vue3 响应式新手"</div>
        <div class="achievement-description">
          你已经入门了，保持学习的热情，逐步掌握更多技能！
        </div>
        <div class="achievement-progress">
          已完成 {{ completedCount }} 个关卡，继续冲刺！
        </div>
      </div>

      <!-- 学习提示 -->
      <div class="tips">
        <div class="tips-title">
          <span>💡</span>
          学习小贴士
        </div>
        <div class="tips-content">
          <p><strong>🎯 当前推荐：</strong> {{ currentTip }}</strong></p>
          <p><strong>⚡ 学习策略：</strong></p>
          <ul style="margin-left: 20px; margin-top: 10px;">
            <li>🏃‍♂️ 循序渐进 - 按顺序完成每个关卡，不要跳跃</li>
            <li>📝 动手实践 - 每个示例都要亲自尝试和修改</li>
            <li>🤔 深入思考 - 理解原理而不仅仅是记住语法</li>
            <li>🔄 复习巩固 - 定期回顾已学内容</li>
            <li>💬 交流讨论 - 与他人分享学习心得</li>
          </ul>
        </div>
      </div>
    </div>
  </div>

  <script>
    const { createApp, ref, computed, reactive } = Vue;

    createApp({
      setup() {
        // 学习路线图数据
        const roadmap = reactive([
          {
            title: "🔮 基础魔法：ref & reactive",
            description: "掌握响应式数据的核心概念，学会创建可观察的数据",
            link: "a.html",
            completed: true
          },
          {
            title: "⚡ 计算魔法：computed",
            description: "学习派生状态的创建，理解计算属性的缓存机制",
            link: "b.html",
            completed: true
          },
          {
            title: "🎯 进阶计算：computed 优化",
            description: "深入理解计算属性的高级用法和性能优化",
            link: "c.html",
            completed: true
          },
          {
            title: "👁️‍🗨️ 监听魔法：watch & watchEffect",
            description: "掌握副作用处理，学会响应数据变化",
            link: "d.html",
            completed: true
          },
          {
            title: "🎨 TS魔法：script setup + 类型推断",
            description: "TypeScript与Vue 3的完美结合，提升开发体验",
            link: "e.html",
            completed: true
          },
          {
            title: "🕳️ 避坑指南：常见陷阱",
            description: "学习常见错误和最佳实践，避免开发陷阱",
            link: "f.html",
            completed: true
          },
          {
            title: "🤝 组件通信：props/emits",
            description: "掌握父子组件间的数据传递和事件通信",
            link: "#",
            completed: false
          },
          {
            title: "🛤️ 路由魔法：Vue Router",
            description: "学习单页应用的路由管理和导航守卫",
            link: "#",
            completed: false
          },
          {
            title: "📦 状态管理：Pinia",
            description: "掌握现代化的状态管理解决方案",
            link: "#",
            completed: false
          },
          {
            title: "🎪 组合式函数",
            description: "学习自定义组合式函数的创建和使用",
            link: "#",
            completed: false
          },
          {
            title: "🔄 依赖注入：provide/inject",
            description: "理解跨组件的数据共享机制",
            link: "#",
            completed: false
          },
          {
            title: "🌊 异步魔法：Suspense",
            description: "掌握异步组件的优雅处理方式",
            link: "#",
            completed: false
          },
          {
            title: "🎯 模板引用：template ref",
            description: "学习DOM元素和组件引用的高级用法",
            link: "#",
            completed: false
          },
          {
            title: "⚡ 性能优化：shallowRef/shallowReactive",
            description: "理解浅层响应式的应用场景",
            link: "#",
            completed: false
          },
          {
            title: "🎨 动画魔法：Transition",
            description: "掌握Vue 3的过渡和动画系统",
            link: "#",
            completed: false
          },
          {
            title: "📡 异步状态：useFetch",
            description: "学习异步数据获取的最佳实践",
            link: "#",
            completed: false
          },
          {
            title: "🧪 测试魔法：单元测试",
            description: "掌握组合式函数的测试方法",
            link: "#",
            completed: false
          },
          {
            title: "🔧 工具函数：toRefs/toRef",
            description: "深入理解响应式工具函数的使用",
            link: "#",
            completed: false
          },
          {
            title: "🎪 高级类型：TypeScript体操",
            description: "掌握Vue 3中的高级类型编程技巧",
            link: "#",
            completed: false
          },
          {
            title: "🔍 源码探索：响应式系统",
            description: "深入理解Vue 3响应式系统的实现原理",
            link: "#",
            completed: false
          },
          {
            title: "🏆 大师挑战：综合项目",
            description: "运用所学知识完成一个完整的响应式应用",
            link: "#",
            completed: false
          }
        ]);

        // 当前进度
        const currentStageIndex = computed(() => {
          return roadmap.findIndex(stage => !stage.completed);
        });

        // 统计信息
        const completedCount = computed(() => {
          return roadmap.filter(stage => stage.completed).length;
        });

        const remainingCount = computed(() => {
          return roadmap.length - completedCount.value;
        });

        const progressPercentage = computed(() => {
          return (completedCount.value / roadmap.length) * 100;
        });

        // 进度文本
        const progressText = computed(() => {
          if (completedCount.value === 0) {
            return "🚀 准备开始你的Vue 3响应式之旅！";
          } else if (completedCount.value < 5) {
            return "🎯 很好！继续保持学习的热情！";
          } else if (completedCount.value < 10) {
            return "✨ 不错！你已经掌握了基础概念！";
          } else if (completedCount.value < 15) {
            return "🌟 优秀！你正在成为响应式专家！";
          } else if (completedCount.value < 20) {
            return "🔥 太棒了！你即将成为小法师！";
          } else {
            return "🏆 恭喜！你已经是Vue 3响应式小法师了！";
          }
        });

        // 当前学习提示
        const currentTip = computed(() => {
          if (currentStageIndex.value === -1) {
            return "你已经完成了所有关卡！可以开始进阶学习或实战项目了。";
          }
          return roadmap[currentStageIndex.value]?.description || "继续加油！";
        });

        // 方法
        const startStage = (index) => {
          if (index <= currentStageIndex.value + 1) {
            console.log(`开始第${index + 1}关：${roadmap[index].title}`);
          }
        };

        const reviewStage = (index) => {
          console.log(`复习第${index + 1}关：${roadmap[index].title}`);
        };

        // 从localStorage加载进度
        const loadProgress = () => {
          const saved = localStorage.getItem('vue3-roadmap-progress');
          if (saved) {
            const progress = JSON.parse(saved);
            roadmap.forEach((stage, index) => {
              if (progress[index] !== undefined) {
                stage.completed = progress[index];
              }
            });
          }
        };

        // 保存进度到localStorage
        const saveProgress = () => {
          const progress = roadmap.map(stage => stage.completed);
          localStorage.setItem('vue3-roadmap-progress', JSON.stringify(progress));
        };

        // 监听进度变化
        watch(completedCount, () => {
          saveProgress();
        });

        // 初始化
        loadProgress();

        return {
          roadmap,
          currentStageIndex,
          completedCount,
          remainingCount,
          progressPercentage,
          progressText,
          currentTip,
          startStage,
          reviewStage
        };
      }
    }).mount('#app');
  </script>
</body>
</html>